package com.bifang.core.excel.gateway;

import cn.hutool.json.JSONUtil;
import com.bifang.common.constant.enums.common.ExcelTypeEnum;
import com.bifang.common.exception.AppException;
import com.bifang.common.util.ServiceRequestUtil;
import com.bifang.common.vo.AppResponse;
import com.bifang.common.vo.SelectVO;
import com.bifang.common.vo.excel.ExcelModelCodeVO;
import com.bifang.common.vo.excel.ExcelModelQueryVO;
import com.bifang.common.vo.excel.ExcelModelVO;
import com.bifang.core.excel.integration.ExcelIntegration;
import com.bifang.core.excel.util.ExcelCommonUtil;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import springfox.documentation.annotations.ApiIgnore;

@RestController
@RequestMapping(value = "/excel")
@Api(tags = "excel管理")
public class ExcelController {
    @Autowired ExcelIntegration excelIntegration;
    @Autowired ExcelCommonUtil excelCommonUtil;
    /** 分页查询数据字典信息 */
    @PostMapping(value = "/query/list", produces = "application/json;charset=UTF-8")
    @ApiOperation(value = "查询excel模板列表", notes = "分页查询excel模板列表")
    public AppResponse<PageInfo<ExcelModelVO>> getPageList(@RequestBody ExcelModelQueryVO req) {
        return AppResponse.successData(excelIntegration.queryList(req));
    }

    @RequestMapping(
            value = "/download/model/byCode",
            method = {RequestMethod.POST, RequestMethod.GET})
    @ApiOperation(value = "根据模板编号下载excel模板", notes = "根据模板编号下载excel模板")
    public void downloadByCode(
            @ApiIgnore HttpServletRequest request,
            @RequestParam Map<String, Object> paramMap,
            @RequestBody(required = false) String body,
            @ApiIgnore HttpServletResponse response) {
        ExcelModelCodeVO vo = null;
        if (StringUtils.isNotBlank(body)) {
            vo = JSONUtil.toBean(body, ExcelModelCodeVO.class);
        } else {
            vo = new ExcelModelCodeVO();
            if (paramMap.get("modelCode") != null) {
                vo.setModelCode(paramMap.get("modelCode").toString());
            }
            if (paramMap.get("version") != null) {
                vo.setVersion(paramMap.get("version").toString());
            }
            if (paramMap.get("rows") != null) {
                vo.setRows(Integer.parseInt(paramMap.get("rows").toString()));
            }
            if (paramMap.get("dictMap") != null) {
                vo.setDictMap(
                        (Map<String, List<SelectVO>>)
                                JSONUtil.parse(JSONUtil.toJsonStr(paramMap.get("dictMap"))));
            }
        }
        vo.setAccessToken(ServiceRequestUtil.getAccessToken(request, response));
        if (StringUtils.isBlank(vo.getModelCode())) {
            throw new AppException("excel模板编号不能为空");
        }

        excelCommonUtil.downloadModel(vo, response);
    }

    @RequestMapping(
            value = "/read/data/byCode",
            method = {RequestMethod.POST})
    @ApiOperation(value = "根据模板编号读取excle文件", notes = "根据模板编号读取excle文件")
    public AppResponse<List<Map<String, Object>>> readByCode(
            @ApiIgnore HttpServletRequest request,
            @RequestHeader Map<String, String> heardMap,
            @RequestParam Map<String, Object> paramMap,
            @ApiIgnore HttpServletResponse response) {
        ExcelModelCodeVO vo = new ExcelModelCodeVO();
        if (paramMap.get("modelCode") != null) {
            vo.setModelCode(paramMap.get("modelCode").toString());
        }
        if (paramMap.get("version") != null) {
            vo.setVersion(paramMap.get("version").toString());
        }
        if (paramMap.get("rows") != null) {
            vo.setRows(Integer.parseInt(paramMap.get("rows").toString()));
        }
        if (paramMap.get("dictMap") != null) {
            vo.setDictMap(
                    (Map<String, List<SelectVO>>)
                            JSONUtil.parse(JSONUtil.toJsonStr(paramMap.get("dictMap"))));
        }
        vo.setAccessToken(ServiceRequestUtil.getAccessToken(request, response));
        if (StringUtils.isBlank(vo.getModelCode())) {
            throw new AppException("excel模板编号不能为空");
        }
        MultipartFile excelFile = null;
        MultipartResolver resolver =
                new CommonsMultipartResolver(request.getSession().getServletContext());
        if (resolver.isMultipart(request)) {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            MultiValueMap<String, MultipartFile> fileMap = multipartRequest.getMultiFileMap();
            if (CollectionUtils.isEmpty(fileMap)) {
                return AppResponse.errorMsg("没有上传文件");
            }
            if (fileMap.keySet().size() > 1) {
                return AppResponse.errorMsg("只能上传一个excel文件");
            }

            for (String key : fileMap.keySet()) {
                List<MultipartFile> fileList = fileMap.get(key);
                if (!CollectionUtils.isEmpty(fileList)) {
                    if (fileList.size() > 1) {
                        throw new AppException("只能上传一个excel文件");
                    }
                    for (MultipartFile file : fileList) {
                        String fileName = file.getOriginalFilename();
                        String suffix = getFileSuffix(fileName);
                        if (ExcelTypeEnum.xls.toString().equals(suffix)
                                || ExcelTypeEnum.xlsx.toString().equals(suffix)) {
                            excelFile = file;
                        } else {
                            throw new AppException("只能上传excel文件");
                        }
                    }
                }
            }
        } else {
            return AppResponse.errorMsg("没有上传文件");
        }
        if (excelFile == null) {
            return AppResponse.errorMsg("没有上传文件");
        }
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            list = excelCommonUtil.readExcel(vo, excelFile.getInputStream());
        } catch (IOException e) {
            return AppResponse.errorMsg("读取文件异常:" + e.getMessage());
        }
        return AppResponse.successData(list);
    }

    /** 根据文件名称获取后缀 输入文件全称, 输出文件后缀 例如： abcde.txt -> txt Or abc.cde$fgh.mp4 -> mp4 */
    private String getFileSuffix(String fileName) {
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }
}
